package org.jsola.hr.service.impl;

import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IOnJobRecordDAO;
import org.jsola.hr.dto.OnJobRecordAddDTO;
import org.jsola.hr.dto.OnJobRecordUpdateDTO;
import org.jsola.hr.entity.EmpInfoDO;
import org.jsola.hr.entity.OnJobRecordDO;
import org.jsola.hr.query.OnJobRecordQuery;
import org.jsola.hr.service.IEmpInfoService;
import org.jsola.hr.service.IOnJobRecordService;
import org.jsola.hr.vo.OnJobRecordListVO;
import org.jsola.hr.vo.OnJobRecordVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 在职记录表
 *
 * @author zhr
 */
@Service("hrOnJobRecordServiceImpl")
public class OnJobRecordServiceImpl implements IOnJobRecordService {

    @Autowired
    private IOnJobRecordDAO onJobRecordDAO;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public OnJobRecordVO save(OnJobRecordAddDTO onJobRecordAddDTO, TokenUser tokenUser) {
        // 转DO
        OnJobRecordDO onJobRecordDO = onJobRecordAddDTO.to(OnJobRecordDO.class);
        // 保存
        onJobRecordDO = save(onJobRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return onJobRecordDO.to(OnJobRecordVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(OnJobRecordUpdateDTO onJobRecordUpdateDTO, TokenUser tokenUser) {
        //转DO
        OnJobRecordDO onJobRecordDO = onJobRecordUpdateDTO.to(OnJobRecordDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(onJobRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... onJobRecordIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) onJobRecordIds);
    }


    @Override
    public OnJobRecordVO selectById(String onJobRecordId, String siteId) {
        OnJobRecordDO onJobRecordDO = selectDOById(onJobRecordId, siteId);
        if (onJobRecordDO == null) {
            return null;
        }
        return onJobRecordDO.to(OnJobRecordVO.class);
    }

    @Override
    public List<OnJobRecordListVO> select(OnJobRecordQuery onJobRecordQuery, String siteId) {
        List<OnJobRecordDO> onJobRecordDOList = selectDO(onJobRecordQuery, siteId);
        if (CollectionUtils.isEmpty(onJobRecordDOList)) {
            return onJobRecordDOList == null ? null : new ArrayList<>();
        }
        return onJobRecordDOList.stream()
                .map(onJobRecordDO -> onJobRecordDO.to(OnJobRecordListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(OnJobRecordQuery onJobRecordQuery, String siteId) {
        Example example = buildExample(onJobRecordQuery, siteId);
        return onJobRecordDAO.selectCountByExample(example);
    }

    @Override
    public Page<OnJobRecordListVO> selectPage(OnJobRecordQuery onJobRecordQuery, String siteId) {
        Example example = buildExample(onJobRecordQuery, siteId);
        Page<OnJobRecordDO> page = onJobRecordDAO.selectPageByExample(example,
                onJobRecordQuery.getPageNo(),
                onJobRecordQuery.getPageSize());

        return page.to(OnJobRecordListVO.class);
    }

    @Override
    public OnJobRecordDO selectDOById(String onJobRecordId, String siteId) {
        return listById(onJobRecordId, siteId);
    }

    @Override
    public List<OnJobRecordDO> selectDO(OnJobRecordQuery onJobRecordQuery, String siteId) {
        Example example = buildExample(onJobRecordQuery, siteId);
        return onJobRecordDAO.selectByExample(example);
    }

    @Override
    public OnJobRecordDO selectByEmpIdAndJoinDate(String empId, String companyId, Date joinDate) {
        Example example = new Example(OnJobRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("empId", empId)
                .andEqualTo("companyId", companyId)
                .andEqualTo("joinDate", joinDate);
        example.orderBy("gmtCreate");
        List<OnJobRecordDO> onJobRecordDOList = onJobRecordDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(onJobRecordDOList)) {
            return null;
        }
        return onJobRecordDOList.get(0);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void saveLeaveDate(String empId, String companyId, Date joinDate, Date turnStraightDate, Date leaveDate, TokenUser tokenUser) {
        ParamException.notNull(empId, "未获取到员工信息，请刷新后重试");
        ParamException.notNull(companyId, "未获取到用工单位信息，请刷新后重试");
        ParamException.notNull(joinDate, "未获取到入职日期，请完善后重试");
        ParamException.notNull(leaveDate, "未获取到离职日期，请完善后重试");
        // 离职后记录在职记录
        OnJobRecordDO leaveJobRecordDO = selectByEmpIdAndJoinDate(empId, companyId, joinDate);
        if (leaveJobRecordDO == null) {
            // 无入职记录 创建入职记录.
            leaveJobRecordDO = new OnJobRecordDO();
            leaveJobRecordDO.setEmpId(empId);
            leaveJobRecordDO.setCompanyId(companyId);
            leaveJobRecordDO.setJoinDate(joinDate);
            leaveJobRecordDO.setTurnStraightDate(turnStraightDate);
            leaveJobRecordDO.setLeaveDate(leaveDate);
            save(leaveJobRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
        } else {
            // 有入职记录 直接放入离职时间
            leaveJobRecordDO.setLeaveDate(leaveDate);
            updateByIdSelective(leaveJobRecordDO, leaveJobRecordDO.getSiteId(), tokenUser.getUserId());
        }
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void saveJoinDate(String empId, String companyId, Date joinDate, Date turnStraightDate, TokenUser tokenUser) {
        // 新员工入职记录
        OnJobRecordDO joinJobRecordDO = selectByEmpIdAndJoinDate(empId, companyId, joinDate);
        if (joinJobRecordDO == null) {
            // 无入职记录 创建入职记录.
            joinJobRecordDO = new OnJobRecordDO();
            joinJobRecordDO.setEmpId(empId);
            joinJobRecordDO.setCompanyId(companyId);
            joinJobRecordDO.setJoinDate(joinDate);
            joinJobRecordDO.setTurnStraightDate(turnStraightDate);
            save(joinJobRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
        } else {
            joinJobRecordDO.setTurnStraightDate(turnStraightDate);
            updateByIdSelective(joinJobRecordDO, joinJobRecordDO.getSiteId(), tokenUser.getUserId());
        }
    }


    /**
     * 根据查询参数，构建example
     *
     * @param onJobRecordQuery 查询参数
     * @param siteId           所属站点id
     * @return example
     */
    private Example buildExample(OnJobRecordQuery onJobRecordQuery, String siteId) {
        Example example = new Example(OnJobRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        // 排序
        ExampleKit.setExampleOrder(example, onJobRecordQuery.getOrders());
        return example;
    }
}




